// CombatWindow.xaml.cs
//
// Copyright (c) 2007 Mike Strobel
//
// This source code is subject to the terms of the Microsoft Reciprocal License (Ms-RL).
// For details, see <http://www.opensource.org/licenses/ms-rl.html>.
//
// All other rights reserved.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Events;
using Microsoft.Practices.ServiceLocation;

using Supremacy.Client.Commands;
using Supremacy.Client.Events;
using Supremacy.Combat;
using Supremacy.Resources;
using Supremacy.Types;

namespace Supremacy.Client
{
    /// <summary>
    /// Interaction logic for CombatWindow.xaml
    /// </summary>

    public partial class CombatWindow
    {
        private CombatUpdate _update;
        private CombatAssets _playerAssets;
        private IClientContext _clientContext;

        public CombatWindow()
        {
            InitializeComponent();
            _clientContext = ServiceLocator.Current.GetInstance<IClientContext>();
            ClientEvents.CombatUpdateReceived.Subscribe(OnCombatUpdateReceived, ThreadOption.UIThread);
        }

        private void OnCombatUpdateReceived(DataEventArgs<CombatUpdate> args)
        {
            HandleCombatUpdate(args.Value);
        }

        private void HandleCombatUpdate(CombatUpdate update)
        {
            _update = update;
            foreach (CombatAssets assets in update.FriendlyAssets)
            {
                if (assets.Owner == _clientContext.LocalPlayer.Empire)
                {
                    _playerAssets = assets;
                    break;
                }
            }
            if (_playerAssets == null)
            {
                _playerAssets = update.FriendlyAssets[0];
            }

            base.DataContext = _update;

            if (update.IsCombatOver)
            {
                if (_update.IsStandoff)
                {
                    HeaderText.Text = ResourceManager.GetString("COMBAT_HEADER") + ": "
                        + String.Format(ResourceManager.GetString("COMBAT_STANDOFF"));
                    SubHeaderText.Text = String.Format(
                        ResourceManager.GetString("COMBAT_TEXT_STANDOFF"),
                        _update.Sector.Name);
                }
                else if (_playerAssets.HasSurvivingAssets)
                {
                    HeaderText.Text = ResourceManager.GetString("COMBAT_HEADER") + ": "
                        + String.Format(ResourceManager.GetString("COMBAT_VICTORY"));
                    SubHeaderText.Text = String.Format(
                        ResourceManager.GetString("COMBAT_TEXT_VICTORY"),
                        _update.Sector.Name);
                }
                else
                {
                    HeaderText.Text = ResourceManager.GetString("COMBAT_HEADER") + ": "
                        + String.Format(ResourceManager.GetString("COMBAT_DEFEAT"));
                    SubHeaderText.Text = String.Format(
                        ResourceManager.GetString("COMBAT_TEXT_DEFEAT"),
                        _update.Sector.Name);
                }
            }
            else
            {
                HeaderText.Text = ResourceManager.GetString("COMBAT_HEADER") + ": "
                    + String.Format(ResourceManager.GetString("COMBAT_ROUND"), _update.RoundNumber);
                SubHeaderText.Text = String.Format(
                    ResourceManager.GetString("COMBAT_TEXT_ENCOUNTER"),
                    _update.Sector.Name);
            }

            PopulateUnitTrees();

            HailButton.IsEnabled = (update.RoundNumber == 1);
            ButtonsPanel.Visibility = update.IsCombatOver ? Visibility.Collapsed : Visibility.Visible;
            CloseButton.Visibility = update.IsCombatOver ? Visibility.Visible : Visibility.Collapsed;
            ButtonsPanel.IsEnabled = true;

            if (!IsVisible)
                Dispatcher.BeginInvoke(DispatcherPriority.Normal, new NullableBoolFunction(ShowDialog));
        }

        private void PopulateUnitTrees()
        {
            DataTemplate itemTemplate = TryFindResource("AssetTreeItemTemplate") as DataTemplate;

            TreeViewItem combatantItems = new TreeViewItem();
            TreeViewItem nonCombatantItems = new TreeViewItem();
            TreeViewItem escapedItems = new TreeViewItem();
            TreeViewItem destroyedItems = new TreeViewItem();

            combatantItems.Header = "Combatant Units";
            nonCombatantItems.Header = "Non-Combatant Units";
            escapedItems.Header = "Escaped Units";
            destroyedItems.Header = "Destroyed Units";

            combatantItems.IsExpanded = true;
            nonCombatantItems.IsExpanded = true;
            escapedItems.IsExpanded = true;
            destroyedItems.IsExpanded = true;

            combatantItems.ItemTemplate = itemTemplate;
            nonCombatantItems.ItemTemplate = itemTemplate;
            escapedItems.ItemTemplate = itemTemplate;
            destroyedItems.ItemTemplate = itemTemplate;

            FriendlyAssetsTree.Items.Clear();

            foreach (CombatAssets friendlyAssets in _update.FriendlyAssets)
            {
                if (friendlyAssets.Station != null)
                {
                    TreeViewItem stationItem = new TreeViewItem();
                    stationItem.Header = friendlyAssets.Station;
                    stationItem.HeaderTemplate = itemTemplate;
                    FriendlyAssetsTree.Items.Add(stationItem);
                }
                foreach (CombatUnit shipStats in friendlyAssets.CombatShips)
                    combatantItems.Items.Add(shipStats);
                foreach (CombatUnit shipStats in friendlyAssets.NonCombatShips)
                    nonCombatantItems.Items.Add(shipStats);
                foreach (CombatUnit shipStats in friendlyAssets.EscapedShips)
                    escapedItems.Items.Add(shipStats);
                foreach (CombatUnit shipStats in friendlyAssets.DestroyedShips)
                    destroyedItems.Items.Add(shipStats);
            }

            if (combatantItems.Items.Count > 0)
                FriendlyAssetsTree.Items.Add(combatantItems);
            if (nonCombatantItems.Items.Count > 0)
                FriendlyAssetsTree.Items.Add(nonCombatantItems);
            if (escapedItems.Items.Count > 0)
                FriendlyAssetsTree.Items.Add(escapedItems);
            if (destroyedItems.Items.Count > 0)
                FriendlyAssetsTree.Items.Add(destroyedItems);

            combatantItems = new TreeViewItem();
            nonCombatantItems = new TreeViewItem();
            escapedItems = new TreeViewItem();
            destroyedItems = new TreeViewItem();

            combatantItems.Header = "Combatant Units";
            nonCombatantItems.Header = "Non-Combatant Units";
            escapedItems.Header = "Escaped Units";
            destroyedItems.Header = "Destroyed Units";

            combatantItems.IsExpanded = true;
            nonCombatantItems.IsExpanded = true;
            escapedItems.IsExpanded = true;
            destroyedItems.IsExpanded = true;

            combatantItems.ItemTemplate = itemTemplate;
            nonCombatantItems.ItemTemplate = itemTemplate;
            escapedItems.ItemTemplate = itemTemplate;
            destroyedItems.ItemTemplate = itemTemplate;

            HostileAssetsTree.Items.Clear();

            foreach (CombatAssets hostileAssets in _update.HostileAssets)
            {
                if (hostileAssets.Station != null)
                {
                    TreeViewItem stationItem = new TreeViewItem();
                    stationItem.Header = hostileAssets.Station;
                    stationItem.HeaderTemplate = itemTemplate;
                    HostileAssetsTree.Items.Add(stationItem);
                }
                foreach (CombatUnit shipStats in hostileAssets.CombatShips)
                    combatantItems.Items.Add(shipStats);
                foreach (CombatUnit shipStats in hostileAssets.NonCombatShips)
                    nonCombatantItems.Items.Add(shipStats);
                foreach (CombatUnit shipStats in hostileAssets.EscapedShips)
                    escapedItems.Items.Add(shipStats);
                foreach (CombatUnit shipStats in hostileAssets.DestroyedShips)
                    destroyedItems.Items.Add(shipStats);
            }

            if (combatantItems.Items.Count > 0)
                HostileAssetsTree.Items.Add(combatantItems);
            if (nonCombatantItems.Items.Count > 0)
                HostileAssetsTree.Items.Add(nonCombatantItems);
            if (escapedItems.Items.Count > 0)
                HostileAssetsTree.Items.Add(escapedItems);
            if (destroyedItems.Items.Count > 0)
                HostileAssetsTree.Items.Add(destroyedItems);
        }

        private void OnOrderButtonClicked(object sender, RoutedEventArgs e)
        {
            CombatOrder order = CombatOrder.Retreat;
            if (sender == EngageButton)
                order = CombatOrder.Engage;
            else if (sender == HailButton)
                order = CombatOrder.Hail;
            ButtonsPanel.IsEnabled = false;
            ClientCommands.SendCombatOrders.Execute(CombatHelper.GenerateBlanketOrders(_playerAssets, order));
        }

        private void OnCloseButtonClicked(object sender, RoutedEventArgs e)
        {
            //base.DialogResult = true;
            base.Visibility = Visibility.Hidden;
        }
    }
}